﻿using System;

namespace Mockery.Core
{
    public interface IArranger
    {
        /// <summary>
        /// Provides the ability to retrieve a registered mock or stub and perform expectations on it
        /// </summary>
        /// <typeparam name="TType">previously registered mock or stub</typeparam>
        /// <param name="actionItem">work delegate</param>
        /// <returns>this instance to support fluent interface</returns>
        Arranger ExpectOn<TType>(Action<TType> actionItem);

        /// <summary>
        /// Allows the adding of a strict mock as defined by Rhino
        /// </summary>
        /// <typeparam name="TType">Type being created as a mock</typeparam>
        /// <returns>the Mocks instance for Fluent style chaining</returns>
        Arranger AddStrictMock<TType>();

        /// <summary>
        /// Allows adding of a dynamic mock as defined by Rhino
        /// </summary>
        /// <typeparam name="TType">Type being created as a dynamic mock</typeparam>
        /// <returns>Mocks instance for Fluent-style chaining</returns>
        Arranger AddDynamicMock<TType>() where TType : class;

        /// <summary>
        /// Allows for adding of a singleton type which typically useful
        /// when using manual mocks
        /// </summary>
        /// <typeparam name="TType">type being added</typeparam>
        /// <param name="value">instance being added</param>
        /// <returns>Mocks instance for Fluent-style chaining</returns>
        Arranger AddSingletonType<TType>(TType value);

        /// <summary>
        /// Allows adding of a stub as defined by Rhino
        /// </summary>
        /// <typeparam name="TType">type being stubbed</typeparam>
        /// <returns></returns>
        Arranger AddStub<TType>();

        /// <summary>
        /// Retrieves an instance of a mock
        /// </summary>
        /// <typeparam name="TValue">value to be retrieved</typeparam>
        /// <returns>mocked instance</returns>
        TValue GetMockedValue<TValue>();
    }
}
